/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package bean.session;

import entity.CompletedGoodsEntity;
import entity.MasterProductionScheduleDailyEntity;
import entity.MasterProductionScheduleMonthlyEntity;
import entity.MasterProductionScheduleWeeklyEntity;
import entity.ProductPercentageQuantityEntity;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import javax.ejb.Stateless;
import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Root;
import type.Month;
import type.ProductionType;
import type.SalesForecastPeriodType;

/**
 *
 * @author wei
 */
@Stateless
public class MasterProductionScheduleWeeklyEntityFacade extends AbstractFacade<MasterProductionScheduleWeeklyEntity> {

    @PersistenceContext(unitName = "MacTeam-warPU")
    private EntityManager em;

    protected EntityManager getEntityManager() {
        return em;
    }

    public MasterProductionScheduleWeeklyEntityFacade() {
        super(MasterProductionScheduleWeeklyEntity.class);
    }

    public DataModel getAllWeeklyMps() {
        Query query = em.createQuery("SELECT m FROM MasterProductionScheduleWeekly m WHERE m.archived!= 'true'");
        return new ListDataModel(query.getResultList());
    }

    public void createWeekly(ArrayList<MasterProductionScheduleDailyEntity> dailyMPS) {

        int year;
        int day;
        int month;
        int weekOfMonth = 1;
        int minusOneWeek = 0;
        Date date;
        Calendar cal = Calendar.getInstance();
        ArrayList<MasterProductionScheduleDailyEntity> thisWeek = new ArrayList<MasterProductionScheduleDailyEntity>();

        day = dailyMPS.get(0).getDayofProduction();
        year = dailyMPS.get(0).getYearOfProduction();
        month = dailyMPS.get(0).getMpsMonthly().getMonthOfProduction().getMonthNum() - 1;
        date = new Date(year - 1900, month, day);

        if (date.getDay() != 1) {
            minusOneWeek = 1;
        }
        for (int i = 0; i < dailyMPS.size(); i++) {
            day = dailyMPS.get(i).getDayofProduction();
            year = dailyMPS.get(i).getYearOfProduction();
            month = dailyMPS.get(i).getMpsMonthly().getMonthOfProduction().getMonthNum() - 1;
            date = new Date(year - 1900, month, day);
            cal.setTime(date);
            if (cal.get(Calendar.WEEK_OF_MONTH) == weekOfMonth) {
                thisWeek.add(dailyMPS.get(i));
                if (i == dailyMPS.size() - 1) {
                    performCreate(thisWeek, weekOfMonth - minusOneWeek);
                }
            } else {
                //perform create
                thisWeek.add(dailyMPS.get(i));
                performCreate(thisWeek, weekOfMonth - minusOneWeek);
                //flush arraylist
                thisWeek.removeAll(dailyMPS);
                //weekOfMonth++
                weekOfMonth++;
                //add to arraylist
                //thisWeek.add(dailyMPS.get(i));

            }
        }

    }

    public void performCreate(ArrayList<MasterProductionScheduleDailyEntity> dailyMPS, int weekOfMonth) {
        System.out.print("dailympssizeisfuckinghere" + dailyMPS.size());
        System.out.print("dailympssizeisfuckinghere222" + dailyMPS.get(0).getId());

        if (weekOfMonth != 0) {

            MasterProductionScheduleWeeklyEntity weeklyMPS = new MasterProductionScheduleWeeklyEntity();
            weeklyMPS.setYearOfProduction(dailyMPS.get(0).getYearOfProduction());
            weeklyMPS.setMonthOfProduction(dailyMPS.get(0).getMpsMonthly().getMonthOfProduction());
            weeklyMPS.setProductionType(dailyMPS.get(0).getProductionType());
            weeklyMPS.setWeeklyWorkingDays1(dailyMPS.size());
            weeklyMPS.setWeekOfProduction(weekOfMonth);
            //weeklyMPS.setMpsMonthly1(dailyMPS.get(0).getMpsMonthly());

            ArrayList<ProductPercentageQuantityEntity> dailyPPQ = new ArrayList<ProductPercentageQuantityEntity>(dailyMPS.get(0).getBreakdownByProduct());
            ArrayList<ProductPercentageQuantityEntity> ppq = new ArrayList<ProductPercentageQuantityEntity>();
            for (int i = 0; i < dailyPPQ.size(); i++) {
                ProductPercentageQuantityEntity p = new ProductPercentageQuantityEntity();
                p.setProduct(dailyPPQ.get(i).getProduct());
                p.setPercentage(dailyPPQ.get(i).getPercentage());
                p.setQuantity(getPPQQuantity(dailyMPS, p.getProduct()));

                if (p.getProduct().getProductName().equals("Classic Nutri Bar (Nuts)")) {
                    weeklyMPS.setClassicNuts(p.getQuantity());
                } else if (p.getProduct().getProductName().equals("Classic Nutri Bar (Fruits)")) {
                    weeklyMPS.setClassicFruits(p.getQuantity());
                } else if (p.getProduct().getProductName().equals("Premium Power Bar (Chocolate Nuts)")) {
                    weeklyMPS.setPremiumNuts(p.getQuantity());
                } else if (p.getProduct().getProductName().equals("Premium Power Bar (Redcurrant Fruits)")) {
                    weeklyMPS.setPremiumFruits(p.getQuantity());
                }

                ppq.add(p);
            }
            weeklyMPS.setBreakdownByProduct1(ppq);
            weeklyMPS.setCreatedBy(dailyMPS.get(0).getCreatedBy());
            create(weeklyMPS);
            weeklyMPS.setMpsDaily(dailyMPS);
            setWeeklyToDailyMPS(weeklyMPS, dailyMPS);
            edit(weeklyMPS);
            //dailyMPS.get(0).getMpsMonthly().getMpsWeekly().add(weeklyMPS);
        } else if (weekOfMonth == 0) {
            //get last month last week mps
            MasterProductionScheduleWeeklyEntity lastWeekMPSOfLastMonth = getLastMonthLastWeekMPS(dailyMPS.get(0).getYearOfProduction(), dailyMPS.get(0).getMpsMonthly().getMonthOfProduction(), dailyMPS.get(0).getProductionType());
            //lastWeekMPSOfLastMonth.setMpsMonthly2(dailyMPS.get(0).getMpsMonthly());
            lastWeekMPSOfLastMonth.setWeeklyWorkingDays2(dailyMPS.size());

            ArrayList<ProductPercentageQuantityEntity> dailyPPQ = new ArrayList<ProductPercentageQuantityEntity>(dailyMPS.get(0).getBreakdownByProduct());
            ArrayList<ProductPercentageQuantityEntity> ppq = new ArrayList<ProductPercentageQuantityEntity>();
            for (int i = 0; i < dailyPPQ.size(); i++) {
                ProductPercentageQuantityEntity p = new ProductPercentageQuantityEntity();
                p.setProduct(dailyPPQ.get(i).getProduct());
                p.setPercentage(dailyPPQ.get(i).getPercentage());
                p.setQuantity(getPPQQuantity(dailyMPS, p.getProduct()));

                if (p.getProduct().getProductName().equals("Classic Nutri Bar (Nuts)")) {
                    lastWeekMPSOfLastMonth.setClassicNuts(p.getQuantity());
                } else if (p.getProduct().getProductName().equals("Classic Nutri Bar (Fruits)")) {
                    lastWeekMPSOfLastMonth.setClassicFruits(p.getQuantity());
                } else if (p.getProduct().getProductName().equals("Premium Power Bar (Chocolate Nuts)")) {
                    lastWeekMPSOfLastMonth.setPremiumNuts(p.getQuantity());
                } else if (p.getProduct().getProductName().equals("Premium Power Bar (Redcurrant Fruits)")) {
                    lastWeekMPSOfLastMonth.setPremiumFruits(p.getQuantity());
                }

                ppq.add(p);
            }
            lastWeekMPSOfLastMonth.setBreakdownByProduct2(ppq);
            for (int i = 0; i < dailyMPS.size(); i++) {
                lastWeekMPSOfLastMonth.getMpsDaily().add(dailyMPS.get(i));
            }
            setWeeklyToDailyMPS(lastWeekMPSOfLastMonth, dailyMPS);
            //dailyMPS.get(0).getMpsMonthly().getMpsWeekly().add(lastWeekMPSOfLastMonth);
            lastWeekMPSOfLastMonth.setLastModifiedBy(dailyMPS.get(0).getCreatedBy());
            edit(lastWeekMPSOfLastMonth);
        }
    }

    private long getPPQQuantity(ArrayList<MasterProductionScheduleDailyEntity> dailyMPS, CompletedGoodsEntity product) {
        long quantity = 0;
        for (int i = 0; i < dailyMPS.size(); i++) {
            ArrayList<ProductPercentageQuantityEntity> dailyPPQ = new ArrayList<ProductPercentageQuantityEntity>(dailyMPS.get(i).getBreakdownByProduct());
            for (int j = 0; j < dailyPPQ.size(); j++) {
                if (dailyPPQ.get(j).getProduct() == product) {
                    quantity = quantity + dailyPPQ.get(j).getQuantity();
                }
            }
        }
        return quantity;
    }

    private void setWeeklyToDailyMPS(MasterProductionScheduleWeeklyEntity weeklyMPS, ArrayList<MasterProductionScheduleDailyEntity> dailyMPS) {
        for (int i = 0; i < dailyMPS.size(); i++) {
            dailyMPS.get(i).setMpsWeekly(weeklyMPS);
        }
    }

    private MasterProductionScheduleWeeklyEntity getLastMonthLastWeekMPS(int year, Month month, ProductionType productionType) {

        if (month.equals(Month.JANUARY)) {
            month = Month.DECEMBER;
            year = year - 1;
        } else {
            month = Month.fromMonthNum(month.getMonthNum() - 1);
        }
        System.out.println(month.getMonthNum()+"Month is here");
        System.out.println(year+"Year is here");

        CriteriaBuilder builder = getEntityManager().getCriteriaBuilder();
        javax.persistence.criteria.CriteriaQuery cq = builder.createQuery();
        Root<MasterProductionScheduleWeeklyEntity> mpsRoot = cq.from(MasterProductionScheduleWeeklyEntity.class);
        cq.select(mpsRoot);
        cq.where(builder.and((builder.equal(mpsRoot.get("archived"), false)), (builder.equal(mpsRoot.get("monthOfProduction"), month)), (builder.equal(mpsRoot.get("yearOfProduction"), year)), (builder.equal(mpsRoot.get("productionType"), productionType))));

        ArrayList<MasterProductionScheduleWeeklyEntity> weeklyMPS = new ArrayList<MasterProductionScheduleWeeklyEntity>();
        for (Object o : em.createQuery(cq).getResultList()) {
            MasterProductionScheduleWeeklyEntity weekly = (MasterProductionScheduleWeeklyEntity) o;
            weeklyMPS.add(weekly);
        }
        System.out.println(weeklyMPS.size());
        return weeklyMPS.get(weeklyMPS.size() - 1);
    }

    public ArrayList<MasterProductionScheduleWeeklyEntity> getWeeklyMPSForMonth(Month month, int year, ProductionType productionType) {
        CriteriaBuilder builder = getEntityManager().getCriteriaBuilder();
        javax.persistence.criteria.CriteriaQuery cq = builder.createQuery();
        Root<MasterProductionScheduleWeeklyEntity> mpsRoot = cq.from(MasterProductionScheduleWeeklyEntity.class);
        cq.select(mpsRoot);
        cq.where(builder.and(builder.equal(mpsRoot.get("archived"), false), builder.equal(mpsRoot.get("monthOfProduction"), month), builder.equal(mpsRoot.get("yearOfProduction"), year), builder.equal(mpsRoot.get("productionType"), productionType)));

        ArrayList<MasterProductionScheduleWeeklyEntity> weeklyMPS = new ArrayList<MasterProductionScheduleWeeklyEntity>();
        for (Object o : em.createQuery(cq).getResultList()) {
            MasterProductionScheduleWeeklyEntity weekly = (MasterProductionScheduleWeeklyEntity) o;
            weeklyMPS.add(weekly);
        }
        return weeklyMPS;
    }

    public long getPreviousMonthOnHand(MasterProductionScheduleWeeklyEntity weeklyMps) {
        ArrayList<MasterProductionScheduleDailyEntity> dailyMPS = new ArrayList<MasterProductionScheduleDailyEntity>(weeklyMps.getMpsDaily());
        MasterProductionScheduleMonthlyEntity mps = dailyMPS.get(0).getMpsMonthly();
        int year = mps.getYearOfProduction();
        Month month = mps.getMonthOfProduction();

        if (mps.getMonthOfProduction().equals(Month.JANUARY)) {
            month = Month.DECEMBER;
            year = year - 1;
        } else {
            month = Month.fromMonthNum(month.getMonthNum() - 1);
        }

        CriteriaBuilder builder = getEntityManager().getCriteriaBuilder();
        javax.persistence.criteria.CriteriaQuery cq = builder.createQuery();
        Root<MasterProductionScheduleMonthlyEntity> mpsRoot = cq.from(MasterProductionScheduleMonthlyEntity.class);
        cq.select(mpsRoot);
        cq.where(builder.and(builder.equal(mpsRoot.get("archived"), false), builder.equal(mpsRoot.get("monthOfProduction"), month), builder.equal(mpsRoot.get("yearOfProduction"), year)));

        MasterProductionScheduleMonthlyEntity m = (MasterProductionScheduleMonthlyEntity) em.createQuery(cq).getResultList().get(0);
        return m.getSafetyStock();
    }

    public DataModel listCreateMPS(SalesForecastPeriodType period, int year, Month month, ProductionType type) {
        CriteriaBuilder builder = getEntityManager().getCriteriaBuilder();
        javax.persistence.criteria.CriteriaQuery cq = builder.createQuery();
        Root<MasterProductionScheduleMonthlyEntity> mpsRoot = cq.from(MasterProductionScheduleMonthlyEntity.class);
        cq.select(mpsRoot);
        cq.where(builder.and(builder.equal(mpsRoot.get("archived"), false), builder.equal(mpsRoot.get("type"), period), builder.equal(mpsRoot.get("yearOfProduction"), year), builder.equal(mpsRoot.get("monthOfProduction"), month), builder.equal(mpsRoot.get("productionType"), type)));

        return new ListDataModel(em.createQuery(cq).getResultList());
    }
}
